#include<iostream>
#include<cstdio>
#include<cstring>
#include<vector>
#include<unistd.h>
#include<pthread.h>
#include"LockGuard.hpp"

using namespace std;

pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;
#define NUM 4

class threadData
{
public:
    threadData(int number)
    {
        threadname = "thread-" + to_string(number);
    }
public:
    string threadname;
};

int tickets = 1000;

// void *getTicket(void *args)
// {
//     threadData *td = static_cast<threadData *>(args);
//     const char *name = td->threadname.c_str();
    
//     while (true)
//     {
//         // 修复1：只加锁1次
//         pthread_mutex_lock(&lock);  

//         if(tickets > 0)
//         {
//             usleep(1000);
//             printf("who=%s, get a ticket: %d\n", name, tickets);
//             tickets--;
//             // 修复2：抢到票后解锁（必须在共享资源操作后）
//             pthread_mutex_unlock(&lock);  
//         }
//         else{
//             // 修复3：没票时也要解锁（否则锁会被持有）
//             pthread_mutex_unlock(&lock);  
//             break;  // 退出循环
//         }

//         // 后续操作在解锁后执行（不占用锁，提高并发效率）
//         usleep(13);  
//     }

//     printf("%s ... quit\n", name);
//     return nullptr;
// }

void* getTicket(void* args)
{
    threadData* td = static_cast<threadData*>(args);
    const char* name = td->threadname.c_str();
    while(true)
    {       
        // if(tickets > 0)
        // {
        //     usleep(1000);
        //     printf("who=%s, get a ticket: %d\n", name, tickets);
        //     tickets--;
        // }
        // else
        // {
        //     break;
        // }
        // usleep(13);
        {
            LockGuard lockguard(&lock);
            if(tickets > 0)
            {
                usleep(1000);
                printf("who=%s, get a ticket: %d\n", name, tickets);
                tickets--;
            }
            else
            {
                break;
            }
        }
        usleep(13);
    }
    printf("%s ... quit\n",name);
    return nullptr;
}

int main()
{
    vector<pthread_t> tids;
    vector<threadData*> thread_datas;
    for(int i = 1; i <= NUM; i++)
    {
        pthread_t tid;
        threadData* td = new threadData(i);
        thread_datas.push_back(td);
        pthread_create(&tid, nullptr, getTicket,thread_datas[i - 1]);
        tids.push_back(tid);
    }
    for(auto thread : tids)
    {
        pthread_join(thread, nullptr);
    }
    for(auto td : thread_datas)
    {
        delete td;
    }
    
    return 0;
}